package yxy.game.pm2.active.module;

import org.joda.time.DateTime;
import yxy.apple.util.redisson.RedisException;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.*;
import yxy.cherry.data.string.GameString;
import yxy.game.pm2.active.ActiveUtil;
import yxy.game.pm2.active.module.actcontrol.activeControl;
import yxy.game.pm2.active.module.actdata.ActDataCenter;
import yxy.game.pm2.active.module.lockorder.LockOrderInfo;
import yxy.game.pm2.active.module.subordinateclass.flop.FlopActive;
import yxy.game.pm2.active.module.subordinateclass.flop.FlopActiveTask;
import yxy.game.pm2.active.module.subordinateclass.flop.FlopCard;
import yxy.game.pm2.active.module.subordinateclass.flop.FlopShop;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.Item;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.ServerBean;
import yxy.game.pm2.bean.currency.CurrencyType;
import yxy.game.pm2.bean.db.dao.MySQLCacheDAO;
import yxy.game.pm2.bean.module.PlayerModule;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.bean.task.Task;
import yxy.game.pm2.bean.task.TaskType;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.mail.MailHandle;
import yxy.game.pm2.module.mail.MailTypeEnum;
import yxy.game.pm2.module.task.TaskHandle;
import yxy.game.pm2.module.tip.TipHandle;
import yxy.game.pm2.module.tip.TipType;

import java.util.*;

public class ActiveModule_翻牌 extends PlayerModule {

    //bean -----------------------------------------------------------
    public static final int acttype = 17;

    private int day;            //第几天
    private DateTime update;    //刷新时间

    private int fcturn;            //翻牌轮次
    private int selectid;          //终极大奖
    private HashMap<Integer, Integer> selectTimes;                  //选择大奖次数  key 奖池id  value 已选次数
    private HashMap<Integer, FlopCard> fcmap = new HashMap<Integer, FlopCard>();    //翻牌信息

    private ArrayList<FlopShop> fss = new ArrayList<FlopShop>();    //翻牌商城

    private FlopActive fa;        //翻牌人物

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    public DateTime getUpdate() {
        return update;
    }

    public void setUpdate(DateTime update) {
        this.update = update;
    }

    public int getFcturn() {
        return fcturn;
    }

    public void setFcturn(int fcturn) {
        this.fcturn = fcturn;
    }

    public int getSelectid() {
        return selectid;
    }

    public void setSelectid(int selectid) {
        this.selectid = selectid;
    }

    public HashMap<Integer, FlopCard> getFcmap() {
        return fcmap;
    }

    public void setFcmap(HashMap<Integer, FlopCard> fcmap) {
        this.fcmap = fcmap;
    }

    public ArrayList<FlopShop> getFss() {
        return fss;
    }

    public void setFss(ArrayList<FlopShop> fss) {
        this.fss = fss;
    }

    public FlopActive getFa() {
        return fa;
    }

    public void setFa(FlopActive fa) {
        this.fa = fa;
    }

    public HashMap<Integer, Integer> getSelectTimes() {
        return selectTimes;
    }

    public void setSelectTimes(HashMap<Integer, Integer> selectTimes) {
        this.selectTimes = selectTimes;
    }

    //func ------------------------------------------------------------

//	public static final int canget = 1;
//	public static final int hadget = 2;
//	public static final int cannotget = 3;

    public static final int type1 = 1;
    public static final int type10 = 10;

    /**
     * 创建实例
     **/
    private static ActiveModule_翻牌 create(String playerCode) {
        PlayerBean pb = PlayerBean.get(playerCode);
        ServerBean sb = ServerBean.get(pb.getServerId());
        activeControl sai = activeControl.get(sb.getAreaId(), acttype);
        if (sai != null) {
            ActiveModule_翻牌 am = new ActiveModule_翻牌();
            am.setPlayerCode(playerCode);
            am.setDay(1);
            am.setTimeline(sai.getTimeline());
            am.setUpdate(DateTime.now());

            //翻牌
            am.setFcturn(1);
            am.setSelectid(0);
            am.setSelectTimes(new HashMap<Integer, Integer>());
            Map<String, actfloprandom> afrmap = ActDataCenter.getAllData(actfloprandom.class, playerCode);
            ArrayList<Integer> afrids = new ArrayList(afrmap.keySet());
            Collections.shuffle(afrids);
            for (int i = 0; i < afrids.size(); i++) {
                actfloprandom afr = afrmap.get(String.valueOf(afrids.get(i)));
                FlopCard fc = new FlopCard();
                fc.setPosition(i + 1);
                fc.setId(afr.getId());
                fc.setFlop(false);
                fc.setGrand(afr.getType() == 2);
                am.getFcmap().put(i + 1, fc);
            }

            //商城
            Map<String, actflopshop> afsmap = ActDataCenter.getAllData(actflopshop.class, playerCode);
            for (actflopshop data : afsmap.values()) {
                FlopShop fs = new FlopShop();
                fs.setId(data.getId());
                fs.setGoodsid(data.getChargeid());
                fs.setLimitnum(data.getLimit());
                am.getFss().add(fs);
            }

            //活跃任务
            FlopActive fa = new FlopActive();
            Map<String, actfloptaskreward> aftrmap = ActDataCenter.getAllData(actfloptaskreward.class, playerCode);
            ArrayList<Integer> groups = new ArrayList<Integer>();
            int newgroup = 0;
            for (actfloptaskreward data : aftrmap.values()) {
                groups.add(data.getGroup());
            }
            Collections.sort(groups);
            newgroup = groups.get(0);
            fa.setActivetaskgroup(newgroup);
            fa.setFinishactivetasknum(0);
            for (actfloptaskreward data : aftrmap.values()) {
                if (newgroup != data.getGroup()) {
                    continue;
                }

                FlopActiveTask fat = new FlopActiveTask();
                fat.setId(data.getId());
                fat.setTaskid(data.getTaskid());

                task taskdata = DataCenter.getData(data.getTaskid(), task.class);
                if (taskdata == null) {
                    continue;
                }

                Task taskbean = Task.create(playerCode, taskdata);
                fat.setTaskcode(taskbean.getCode());
                fa.getFats().add(fat);
            }

            am.setFa(fa);

            am.set();
            TaskHandle.handle(playerCode, TaskType.统计型_登录_次数, 1);
            return am;
        }

        return null;
    }

    //刷新 重新开启
    private void reset() {

//        //重置道具
//        try {
//            Currency item = Item.get(getPlayerCode(), CurrencyType.CT_物品, 1038);    //翻牌 - 翻牌道具
//            Currency.minus(getPlayerCode(), item);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        //重置道具
//        try {
//            Currency item = Item.get(getPlayerCode(), CurrencyType.CT_物品, 1040);    //翻牌 - 夺宝道具
//            Currency.minus(getPlayerCode(), item);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        setDay(1);
        setUpdate(DateTime.now());
        setSelectTimes(new HashMap<Integer, Integer>());
        //翻牌
        setFcturn(1);
        setFcmap(new HashMap<Integer, FlopCard>());
        Map<String, actfloprandom> afrmap = ActDataCenter.getAllData(actfloprandom.class, getPlayerCode());
        ArrayList<Integer> afrids = new ArrayList(afrmap.keySet());
        Collections.shuffle(afrids);
        for (int i = 0; i < afrids.size(); i++) {
            actfloprandom afr = afrmap.get(String.valueOf(afrids.get(i)));
            FlopCard fc = new FlopCard();
            fc.setPosition(i + 1);
            fc.setId(afr.getId());
            fc.setFlop(false);
            fc.setGrand(afr.getType() == 2);
            getFcmap().put(i + 1, fc);
        }

        //商城
        setFss(new ArrayList<FlopShop>());
        Map<String, actflopshop> afsmap = ActDataCenter.getAllData(actflopshop.class, getPlayerCode());
        for (actflopshop data : afsmap.values()) {
            FlopShop fs = new FlopShop();
            fs.setId(data.getId());
            fs.setGoodsid(data.getChargeid());
            fs.setLimitnum(data.getLimit());
            getFss().add(fs);
        }

        //活跃任务
        for (FlopActiveTask fat : getFa().getFats()) {
            Task.remove(getPlayerCode(), fat.getTaskcode());
        }
        FlopActive fa = new FlopActive();
        Map<String, actfloptaskreward> aftrmap = ActDataCenter.getAllData(actfloptaskreward.class, getPlayerCode());
        ArrayList<Integer> groups = new ArrayList<Integer>();
        int newgroup = 0;
        for (actfloptaskreward data : aftrmap.values()) {
            groups.add(data.getGroup());
        }
        Collections.sort(groups);
        newgroup = groups.get(0);
        fa.setActivetaskgroup(newgroup);
        fa.setFinishactivetasknum(0);
        for (actfloptaskreward data : aftrmap.values()) {
            if (newgroup != data.getGroup()) {
                continue;
            }

            FlopActiveTask fat = new FlopActiveTask();
            fat.setId(data.getId());
            fat.setTaskid(data.getTaskid());

            task taskdata = DataCenter.getData(data.getTaskid(), task.class);
            if (taskdata == null) {
                continue;
            }

            Task taskbean = Task.create(getPlayerCode(), taskdata);
            fat.setTaskcode(taskbean.getCode());
            fa.getFats().add(fat);
        }

        setFa(fa);

        set();
        TaskHandle.handle(getPlayerCode(), TaskType.统计型_登录_次数, 1);
    }

    /**
     * 更新
     **/
    private void update() {
        PlayerBean pb = PlayerBean.get(getPlayerCode());
        ServerBean sb = ServerBean.get(pb.getServerId());
        activeControl sai = activeControl.get(String.valueOf(sb.getAreaId()), String.valueOf(acttype));
        if (sai == null) {
            return;
        }

        //关闭活动
        if (!sai.running()) {
            try {
                //todo 活动关闭，清除背包的没消耗完的活动道具
                //如果背包存在就转成对应物品邮件发送
                Currency currency1 = Item.get(getPlayerCode(), CurrencyType.CT_物品, 1038);
                if (currency1.getNumber() > 0 ) {
                    List<Currency> list1 = new ArrayList<>();
                    list1.add(currency1);
                    new CurrencyHandle().cost(getPlayerCode(), CCReason.翻牌活动消耗道具清空, list1);

                    item item1 = DataCenter.getData(1038, item.class);

                    //邮件补偿
                    List<Currency> list2 = new ArrayList<>();
                    Currency reward1 = Currency.create(item1.getReclaimtype(), item1.getReclaimid(), currency1.getNumber() * item1.getReclaimnum());
                    if (reward1 != null) list2.add(reward1);
                    String title = GameString.活动结束自动回收_title().getText();
                    long num = currency1.getNumber();
                    String content = GameString.活动结束自动回收_msg("翻牌", "" + num, "" + item1.getName(), "" + num * item1.getReclaimnum()).getText();
                    new MailHandle().sendMail(getPlayerCode(), MailTypeEnum.Mail, title, content, CCReason.翻牌活动消耗道具清空, list2);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        //关闭活动
        if (!sai.running() && running()) {
            setTimeline(sai.getTimeline());
            set();
            return;
        }


        //开启活动
        if (sai.running() && !running()) {
            setTimeline(sai.getTimeline());
            reset();
        }

        if (!running()) {
            return;
        }

        //更新
        DateTime now = DateTime.now();
        int days = ActiveUtil.days(getUpdate(), now);
        if (days >= 1) {        //转天更新
            int newdays = getDay() + days;
            setDay(newdays);
            setUpdate(now);

            //活跃任务
            for (FlopActiveTask fat : getFa().getFats()) {
                Task.remove(getPlayerCode(), fat.getTaskcode());
            }

            FlopActive fa = getFa();
            Map<String, actfloptaskreward> aftrmap = ActDataCenter.getAllData(actfloptaskreward.class, getPlayerCode());
            ArrayList<Integer> groups = new ArrayList<Integer>();
            int newgroup = fa.getActivetaskgroup() + 1;
            for (actfloptaskreward data : aftrmap.values()) {
                groups.add(data.getGroup());
            }
            if (!groups.contains(newgroup)) {
                Collections.sort(groups);
                newgroup = groups.get(0);
            }

            fa.setFinishactivetasknumboxgetids(new ArrayList<Integer>());
            fa.setActivetaskgroup(newgroup);
            fa.setFinishactivetasknum(0);
            fa.setFats(new ArrayList<FlopActiveTask>());

            for (actfloptaskreward data : aftrmap.values()) {
                if (newgroup != data.getGroup()) {
                    continue;
                }

                FlopActiveTask fat = new FlopActiveTask();
                fat.setId(data.getId());
                fat.setTaskid(data.getTaskid());

                task taskdata = DataCenter.getData(data.getTaskid(), task.class);
                if (taskdata == null) {
                    continue;
                }

                Task taskbean = Task.create(getPlayerCode(), taskdata);
                fat.setTaskcode(taskbean.getCode());
                fa.getFats().add(fat);
            }

            set();
            TaskHandle.handle(getPlayerCode(), TaskType.统计型_登录_次数, 1);
        }

        //更新 检查锁单
        boolean save = false;
        for (FlopShop fs : getFss()) {
            ArrayList<String> removemyorderids = new ArrayList<String>();
            DateTime nowtime = DateTime.now();
            for (String myorderid : fs.getLock().keySet()) {
                if (nowtime.getMillis() - fs.getLock().get(myorderid).getMillis() >= LockOrderInfo.lockTime()) {
                    removemyorderids.add(myorderid);
                    save = true;
                }
            }

            for (String myorderid : removemyorderids) {
                fs.getLock().remove(myorderid);
            }
        }

        if (save) {
            set();
        }
    }

    //翻牌 下一轮
    public void fcnext() {
        int newturn = getFcturn() + 1;
        try {
            if (this.tryLock()) {
                HashMap<Integer, Integer> selectTimes = getSelectTimes();
                if (selectTimes == null) {
                    selectTimes = new HashMap<Integer, Integer>();

                }

                if (selectTimes.get(getSelectid()) == null) {
                    selectTimes.put(getSelectid(), 1);
                } else {
                    selectTimes.put(getSelectid(), selectTimes.get(getSelectid()) + 1);
                }

            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            this.unlock();
        }

        setFcturn(newturn);
        setFcmap(new HashMap<Integer, FlopCard>());
        setSelectid(0);


        Map<String, actfloprandom> afrmap = ActDataCenter.getAllData(actfloprandom.class, getPlayerCode());
        ArrayList<Integer> afrids = new ArrayList(afrmap.keySet());
        Collections.shuffle(afrids);
        for (int i = 0; i < afrids.size(); i++) {
            actfloprandom afr = afrmap.get(String.valueOf(afrids.get(i)));
            FlopCard fc = new FlopCard();
            fc.setPosition(i + 1);
            fc.setId(afr.getId());
            fc.setFlop(false);
            fc.setGrand(afr.getType() == 2);
            getFcmap().put(i + 1, fc);
        }

        set();
    }

    /**
     * 能否购买
     *
     * @param goodsid
     * @return
     */
    public int canbuy(int goodsid) {
        for (FlopShop fs : getFss()) {
            if (fs.getGoodsid() == goodsid) {
                if (fs.getBuy().size() + fs.getLock().size() < fs.getLimitnum()) {
                    return DrawStatus.canget.getStatus();
                }
            }
        }

        return DrawStatus.cannotget.getStatus();
    }

    /**
     * 锁单
     *
     * @param goodsid
     * @param myorderid
     */
    public void lockorder(int goodsid, String myorderid) {
        for (FlopShop fs : getFss()) {
            if (fs.getGoodsid() == goodsid) {
                fs.getLock().put(myorderid, DateTime.now());
            }
        }
        set();
    }

    /**
     * 解锁单
     *
     * @param goodsid
     */
    public void unlockorder(int goodsid, String myorderid) {
        for (FlopShop fs : getFss()) {
            if (fs.getGoodsid() == goodsid) {
                fs.getLock().remove(myorderid);
            }
        }
        set();
    }

    /**
     * 处理购买
     *
     * @param goodsid
     * @param myorderid
     */
    public void handlebuy(int goodsid, String myorderid) {
        for (FlopShop fs : getFss()) {
            if (fs.getGoodsid() == goodsid) {
                fs.getLock().remove(myorderid);
                fs.getBuy().put(myorderid, DateTime.now());
            }
        }
        set();
    }

    //redis -----------------------------------------------

    /**
     * 获取redis key
     **/
    static private String key(String playerCode) {
        return String.format("PLAYER:%s:ACTIVE:%S", playerCode, acttype);
    }

    /**
     * 保存
     **/
    public void set() {
        try {
            setv(key(getPlayerCode()), this);
            check();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取ActiveModule_征战日志
     *
     * @param playerCode
     * @return
     */
    static public ActiveModule_翻牌 get(String playerCode, Boolean isNewPlayer) {
        try {
            ActiveModule_翻牌 module = getv(key(playerCode));

            //新用户不需要去查数据库
            if (module == null && !isNewPlayer) {
                module = MySQLCacheDAO.getV(key(playerCode), ActiveModule_翻牌.class);
                if (module != null) {
                    module.set();
                }//同步到redis
            }

            if (module == null) {
                module = create(playerCode);
            }
            if (module == null) {
                return null;
            }

            module.update();
            module.check();

            return module;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 检查红点，活动是否开启
     **/
    public void check() {
        if (running()) {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.开启);
        } else {
            new ActOpenHandle().updateActOpen(getPlayerCode(), acttype, OpenType.关闭);
            new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_抽奖, false);
            new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_活跃任务, false);
            return;
        }

        checkFlopCard();
        checkActive();
//		checkTurn();
    }

    //翻牌 - 翻牌 检查红点
    private void checkFlopCard() {
        //翻牌
        try {
            Currency item = Item.get(getPlayerCode(), CurrencyType.CT_物品, 1038);    //翻牌 - 翻牌道具
            if (item.getNumber() > 0) {
                new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_抽奖, true);
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_抽奖, false);
    }

    //翻牌 - 夺宝 检查红点
//	private void checkTurn() {
//		try {
//			Currency item = Item.get(getPlayerCode(), CurrencyType.CT_物品, 1040);	//翻牌 - 夺宝道具
//			if(item.getNumber() > 0) {
//				new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_活跃任务, true);
//				return;
//			}
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//		new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_活跃任务, false);
//	}

    //活跃活动 检查红点
    private void checkActive() {
        FlopActive fa = getFa();

        //活跃任务
        for (FlopActiveTask fat : fa.getFats()) {
            String taskcode = fat.getTaskcode();
            Task taskbean = Task.get(getPlayerCode(), taskcode);

            if (taskbean != null && taskbean.isFinish() && !taskbean.isReward()) {
                new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_活跃任务, true);
                return;
            }
        }

        //活跃任务完成数宝箱
        Map<String, actflopstagereward> afsrmap = ActDataCenter.getAllData(actflopstagereward.class, getPlayerCode());
        if (afsrmap.size() < fa.getFinishactivetasknumboxgetids().size()) {
            if (fa.getFinishactivetasknumboxgetids().size() < afsrmap.size()) {
                for (actflopstagereward data : afsrmap.values()) {
                    if (fa.getFinishactivetasknumboxgetids().contains(data.getId())) {
                        continue;
                    }

                    if (fa.getFinishactivetasknum() >= data.getCondition()) {
                        new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_活跃任务, true);
                        return;
                    }
                }
            }
        }

        //翻牌夺宝
        try {
            Currency item = Item.get(getPlayerCode(), CurrencyType.CT_物品, 1040);    //翻牌 - 夺宝道具
            if (item.getNumber() > 0) {
                new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_活跃任务, true);
                return;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        new TipHandle().updateTip(getPlayerCode(), TipType.活动_翻牌_活跃任务, false);
    }

    //存储到数据库的方法
    public static void saveToDB(String playerCode) {
        try {
            String key = key(playerCode);
            if (touchBucket(key).isExists()) {
                ActiveModule_翻牌 activeModule_翻牌 = getv(key(playerCode));
                MySQLCacheDAO.setV(key, activeModule_翻牌);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //从redis移走数据的操作
    public static void removeAllFromRedis(String playerCode) {
        try {
            touchBucket(key(playerCode)).delete();
        } catch (RedisException e) {
            e.printStackTrace();
        }
    }

    //lock --------------------------------------------------------
    @Override
    public String lockKey() {
        return String.format("lock:%s", key(getPlayerCode()));
    }


}
